package com.yf.serviceImpl;

import com.yf.bean.BaseResponse;
import com.yf.bean.CommentBean;
import com.yf.bean.CommentOpBean;
import com.yf.dao.CommentDao;
import com.yf.service.CommentService;
import com.yf.service.RedisService;
import com.yf.utils.Constant;
import com.yf.utils.UserContext;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Log4j2
@Service("CommentServiceImpl")
public class CommentServiceImpl implements CommentService {
    @Autowired
    CommentDao commentDao;

    @Autowired
    RedisService redisService;

    @Override
    public int addComment(CommentBean bean) {
        Integer pid = bean.getPid();
        if (pid == null || pid <= 0) {
            return -1;
        }
        String content = bean.getContent();
        if (content == null || content.length() == 0 || content.length() > 500) {
            return -2;
        }
        Integer uid = UserContext.getUserId();
        if (uid <= 0) {
            return -3;
        }
        bean.setSid(uid);
        bean.setLike(0);
        bean.setDislike(0);
        bean.setValid((short) 1);
        return commentDao.addComment(bean);
    }

    @Override
    public int addReply(CommentBean bean) {
        Integer cid = bean.getCid();
        if (cid == null || cid <= 0) {
            return -1;
        }

        Integer rid = bean.getRid();
        if (rid == null || rid <= 0) {
            return -2;
        }

        Integer refId = bean.getRefId();
        if (refId == null || refId <= 0) {
            return -3;
        }

        String content = bean.getContent();
        if (content == null || content.length() == 0 || content.length() > 500) {
            return -4;
        }

        Integer uid = UserContext.getUserId();
        if (uid <= 0) {
            return -5;
        }
        bean.setSid(uid);
        bean.setDislike(0);
        bean.setLike(0);
//        bean.setValid((short) 1);
        bean.setValid((short) 2);
        return commentDao.addComment(bean);
    }

    @Override
    public int updateLike(Integer id, Integer like) {
        Map<String, Object> params = new HashMap<>(2);
        params.put("id", id);
        params.put("like", like);
        return commentDao.updateLike(params);
    }

    @Override
    public int updateDislike(Integer id, Integer dislike) {
        Map<String, Object> params = new HashMap<>(2);
        params.put("id", id);
        params.put("dislike", dislike);
        return commentDao.updateDislike(params);
    }

    void cacheLikeDislike(Integer id) {
        final CommentBean comment = commentDao.getCommentById(id);
        if (comment != null) {
            redisService.addDisLike(id, comment.getDislike());
            redisService.addLike(id, comment.getLike());
        }
    }


    @Override
    public boolean opDislike(Integer id, int opType) {
        final Integer uid = UserContext.getUserId();
        if (uid <= 0) {
            return false;
        }
        final Integer disLike = redisService.getDisLike(id);
        if (disLike == -1) {
            cacheLikeDislike(id);
        }
        Map<String, Object> params = new HashMap<>();
        params.put("cid", id);
        params.put("uid", uid);
        final Short opOrigin = commentDao.queryCommentOp(params);

        if (opType == 0) {
            params.put("op", Constant.NULL_OP);
            if (opOrigin != null) {
                commentDao.updateCommentOp(params);
            } else {
                commentDao.addCommentOp(params);
            }
            return redisService.decDislike(id);
        }

        params.put("op", Constant.DISLIKE_OP);
        if (opOrigin != null) {
            if (opOrigin.equals(Constant.LIKE_OP)) {
                redisService.decLike(id);
                commentDao.updateCommentOp(params);
            }
        } else {
            commentDao.addCommentOp(params);
        }

        return redisService.incDisLike(id);
    }

    @Override
    public boolean opLike(Integer id, int opType) {
        final Integer uid = UserContext.getUserId();
        if (uid <= 0) {
            return false;
        }

        final Integer like = redisService.getLike(id);
        if (like == -1) {
            cacheLikeDislike(id);
        }

        Map<String, Object> params = new HashMap<>();
        params.put("cid", id);
        params.put("uid", uid);
        final Short opOrigin = commentDao.queryCommentOp(params);

        if (opType == 0) {
            params.put("op", Constant.NULL_OP);
            if (opOrigin != null) {
                commentDao.updateCommentOp(params);
            } else {
                commentDao.addCommentOp(params);
            }
            return redisService.decLike(id);
        }

        params.put("op", Constant.LIKE_OP);
        if (opOrigin != null) {
            if (opOrigin.equals(Constant.DISLIKE_OP)) {
                redisService.decDislike(id);
                commentDao.updateCommentOp(params);
            }
        } else {
            commentDao.addCommentOp(params);
        }

        return redisService.incLike(id);
    }

    int[] getLikeDataFromCache(Integer id) {
        final Integer like = redisService.getLike(id);
        if (like == -1) {
            return null;
        }
        final Integer dislike = redisService.getDisLike(id);
        return new int[]{like, dislike};
    }

    void cacheLikeDislike(Integer id, Integer like, Integer dislike) {
        redisService.addLike(id, like);
        redisService.addDisLike(id, dislike);
    }

    @Override
    public List<CommentBean> getCommentByPid(Map<String, Object> params) {
        return getComments(params, 1);
    }

    public List<CommentBean> getComments(Map<String, Object> params, int type) {
        List<CommentBean> commentBeans;
        if (type == 0) {
            commentBeans = commentDao.getCommentByCid(params);
        } else {
            commentBeans = commentDao.getCommentByPid(params);
        }
        Map<String, Object> opParams = new HashMap<>(2);
        for (CommentBean e : commentBeans) {
            final int[] cache = getLikeDataFromCache(e.getId());
            if (cache == null) {
                cacheLikeDislike(e.getId(), e.getLike(), e.getDislike());
            } else {
                e.setLike(cache[0]);
                e.setDislike(cache[1]);
            }
            final Integer uid = UserContext.getUserId();
            opParams.put("uid", uid);
            opParams.put("cid", e.getId());
            Short i = commentDao.queryCommentOp(opParams);
            if (i == null) {
                i = 0;
            }
            e.setUserLikeOp(i);
        }
        return commentBeans;
    }

    @Override
    public List<CommentBean> getCommentByCid(Map<String, Object> params) {
        return getComments(params, 0);
    }

    @Override
    public int deleteComment(Integer id) {
        final Integer uid = UserContext.getUserId();
        if (uid <= 0) {
            return -1;
        }
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        params.put("sid", uid);
        final int i = commentDao.checkCommentOwner(params);
        if (i > 0) {
            return commentDao.deleteComment(id);
        }
        return -2;
    }

    @Override
    public int getUserUnreadMsg() {
        final Integer uid = UserContext.getUserId();
        if (uid <= 0) {
            return 0;
        }
        return commentDao.getUserUnread(uid);
    }
}
